/*
*
*	The Gimme ECMAScript Library by Stephen Stchur
*	"Taking the pain out of Javascript!"
*
*	Copyright (c) Microsoft Corporation.  All rights reserved.
*
*	Description:
*	Gimme Query Module:	Gimme's CSS Querying Engine
*
*	Requires:
*	Nothing
*
*/

var Gimme = function()
{
	// include fetch
	#include:./src/fetch.js
	
	// private "classes"
	function GimmeObject(collection)
	{
		Array.prototype.push.apply(this, collection);
	}
	GimmeObject.prototype =
	{
		length: Array.prototype.length,
		entities: function()
		{
			return Array.prototype.slice.apply(this);
		},		
		sort: function(sortFn)
		{
			Array.prototype.sort.call(this, sortFn);
			return this;
		},
		reverse: function()
		{
			Array.prototype.reverse.call(this);
			return this;
		},
		push: function()
		{
			Array.prototype.push.apply(this, arguments);
			return this;
		},
		pop: function()
		{
			Array.prototype.pop.call(this);
			return this;
		},
		shift: function()
		{
			Array.prototype.shift.call(this)
			return this;
		},
		unshift: function()
		{
			Array.prototype.unshift.apply(this, arguments);
			return this;
		},
		slice: function()
		{
			return new GimmeObject(Array.prototype.slice.apply(this, arguments));
		},
		splice: function()
		{
			return new GimmeObject(Array.prototype.splice.apply(this, arguments));
		},
		concat: function(gim)
		{
			return new GimmeObject(Array.prototype.concat.apply(this.entities(), gim.entities && gim.entities() || arguments));
		}
	};		
	////
	
	
	// the actual Gimme(..) function
	function Gimme(selector, root)
	{
		var entities =
			!selector && []
			|| (root || typeof selector === 'string') && fetch(selector, root)
			|| selector instanceof Array && selector
			|| [ selector ];
		
		return new GimmeObject(entities);
	}		
	////
	
	
	// Gimme Helper namespace
	Gimme.Helper =
	{
		index_of: fetch.Utility.index_of,
		contains: fetch.Utility.contains,
		unique: fetch.Utility.unique,
		has_class: fetch.Utility.has_class,
		get_attr: fetch.Utility.get_attr,
		get_guid: function()
		{
			var counter = 0;
			return function(elem)
			{
				if (!elem)
				{
					return '';
				}
				if (elem === window)
				{
					return 'win';
				}
				else if (elem === document)
				{
					return 'doc';
				}
				else if (elem.uniqueID)
				{
					return elem.uniqueID;
				}

				var ex = '__$gimme$_guid__';
				if (typeof elem[ex] === 'undefined')
				{
					elem[ex] = ex + counter++;
				}
				return elem[ex];
			}
		}()
	};
	////
	
	// Gimme Browser namespace
	Gimme.Browser = function()
	{
		var ua = navigator.userAgent.toLowerCase();
		return {
			is_ie: typeof ActiveXObject !== 'undefined',
			is_opera: typeof window.opera !== 'undefined',
			is_khtml: ua.indexOf('khtml') !== -1,
			is_gecko: ua.indexOf('khtml') === -1 && ua.indexOf('gecko') !== -1,
			is_in_quirks_mode: document.compatMode === 'BackCompat'
		};		
	}();
	
	// Gimme undefined (safe from any other library purposely or inadvertently overwriting the native undefined value)
	Gimme.undefined = ({})._$gimme$_undefined;
	////
	
	
	// the Gimme extension property
	Gimme.ext = GimmeObject.prototype;
	////
	
	
	// expose Fetch as Gimme.query
	Gimme.query = fetch;
	////
	
	return Gimme;
}();
